/*
 * Excel to publishing in Spread DLL code
 * Copyright 2008, James E. Kleckner

  This file is part of spread-excel.

  spread-excel is free software: you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  spread-excel is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

 */

/*
Place these functions into a visual basic module:
============================
' Testing functions:

Declare Function ExcelSpreadPub_sp_connect_wc Lib "ExcelSpreadPub.dll" _
    (ByRef server As String, ByRef client As String) As Integer

Declare Function ExcelSpreadPub_sp_pub_wc Lib "ExcelSpreadPub.dll" _
    (ByRef topic As String, ByRef value As String) As Integer

Declare Function ExcelSpreadPub_square Lib "ExcelSpreadPub.dll" _
    (ByVal x As Double) As Double

' Misc other types of functions:

Declare Function ExcelSpreadPub_count_strings Lib "ExcelSpreadPub.dll" _
    (ByRef x As String, ByRef y As String) As Double

'Declare Function ExcelSpreadPub_double_string Lib "ExcelSpreadPub.dll" _
'    (ByRef retVal As String, ByRef y As String) As Double

Declare Function ExcelSpreadPub_charnum Lib "ExcelSpreadPub.dll" _
    (ByRef i As Long, ByRef y As String) As Double

'Declare Sub ExcelSpreadPub_concat_strings Lib "ExcelSpreadPub.dll" _
'    (ByRef retVal As String, ByRef x As String, ByRef y As String)

Function ExcelSpreadPub_wrap_concat( s1 as String, s2 as String) as String
'
    'Dim retString As String
    'retString = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
    'Call ExcelSpreadPub_concat_strings(retString, s1, s2)
    'ExcelSpreadPub_wrap_concat = retString
    ExcelSpreadPub_wrap_concat = "disabled"
End Function

*/


#include "windef.h"
#include "winnt.h"
#include "ExcelSpreadPub.h"

#if 1
#include "sp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>

// wip wip wip: These statics are visible to all callers of this DLL...
//static        char    s_user[80];
//static  char    s_spread_name[80];
static  char    s_private_group[MAX_GROUP_NAME];
static  int     s_mboxConnected = 0;
static  mailbox s_mbox;

// Initialization of the DLL
BOOL WINAPI
DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            // Code to run when the DLL is loaded
#if 0
            if (! s_mboxConnected)
            {
                int ret;
                // Connect to the mailbox
                ret = SP_connect("4803@mask2", "excel", 0, 0, &s_mbox, s_private_group);
                //ret = SP_connect("4803@mask2", NULL, 0, 0, &s_mbox, s_private_group);
                if( ret >= 0 )
                {
                    s_mboxConnected = 1;
                }
            }
#endif
            break;

        case DLL_PROCESS_DETACH:
#if 1
            // Code to run when the DLL is freed
            if (s_mboxConnected)
            {
                SP_disconnect(s_mbox);
                s_mboxConnected = 0;
            }
#endif
            break;

        case DLL_THREAD_ATTACH:
            // Code to run when a thread is created during the DLL's lifetime
            break;

        case DLL_THREAD_DETACH:
            // Code to run when a thread ends normally.
            break;
    }
    return TRUE;
}


#if 1
DLLIMPORT int pascal  
ExcelSpreadPub_sp_connect_wc(WCHAR** server, WCHAR** client)
{
    int    ret;
    char   serverName[1024];
    char   clientName[1024];
    //
    wcstombs(serverName, *server, 1023);
    wcstombs(clientName, *client, 1023);
    //
    if (s_mboxConnected)
    {
        SP_disconnect(s_mbox);
        s_mboxConnected = 0;
    }
//##printf("ExcelSpreadPub: connect to server '%s' as client '%s'\n", serverName, clientName);
    ret = SP_connect(serverName, clientName, 0, 0, &s_mbox, s_private_group);
//##printf("ExcelSpreadPub: SP_connect returned: '%d' and private group returned: '%s'\n", ret, s_private_group);
    if( ret >= 0 )
    {
        s_mboxConnected = 1;
#if 1
        char*  mess1 = "test message 1";
        char*  mess2 = "test message 2";
        /* multicast a message to that group */
        SP_multicast( s_mbox, SAFE_MESS, "foo",       1, strlen(mess1), mess1 );
        SP_multicast( s_mbox, SAFE_MESS, "exceltest", 1, strlen(mess2), mess2 );
#endif
    }

    return ret;
}
#else
DLLIMPORT int pascal  
ExcelSpreadPub_sp_connect_wc(WCHAR** server, WCHAR** client)
{
    return -1;
}
#endif

#if 1
DLLIMPORT int pascal 
ExcelSpreadPub_sp_pub_wc(WCHAR** topicName, WCHAR** topicData )
{
    char messBuf[2048];
    char topic[MAX_GROUP_NAME];
    int num;
    wcstombs(topic, *topicName, MAX_GROUP_NAME);
    num = wcstombs(messBuf, *topicData, 2047);
    if (num >= 0) {
        int ret = SP_multicast( s_mbox, FIFO_MESS, topic, 1, num, messBuf );
//##    printf("ExcelSpreadPub: SP_multicast sent '%s' to '%s' and returned: '%d'\n", messBuf, topic, ret);
        return ret;
    }
    return -1;
}
#else

DLLIMPORT int pascal 
ExcelSpreadPub_sp_pub_wc(WCHAR** topicName, WCHAR** topicData )
{
    return -1;
    //return SP_multicast( s_mbox, SAFE_MESS, "foo",             1, 5, "hello" );
}
#endif


#if 1
DLLIMPORT int pascal  
ExcelSpreadPub_sp_connect_cp(char* server, char* client)
{
    int    ret;
    char   serverName[1024];
    char   clientName[1024];
    //
    strncpy(serverName, server, 1023);
    strncpy(clientName, client, 1023);
    //
    if (s_mboxConnected)
    {
        SP_disconnect(s_mbox);
        s_mboxConnected = 0;
    }
//##printf("ExcelSpreadPub: connect to server '%s' as client '%s'\n", serverName, clientName);
    ret = SP_connect(serverName, clientName, 0, 0, &s_mbox, s_private_group);
//##printf("ExcelSpreadPub: SP_connect returned: '%d' and private group returned: '%s'\n", ret, s_private_group);
    if( ret >= 0 )
    {
        s_mboxConnected = 1;
    }

    return ret;
}
#else
DLLIMPORT int pascal  
ExcelSpreadPub_sp_connect_cp(char* server, char* client)
{
    return -1;
}
#endif

#if 1
DLLIMPORT int pascal 
ExcelSpreadPub_sp_pub_cp(char* topicName, char* topicData )
{
    char messBuf[2048];
    char topic[MAX_GROUP_NAME];
    int num;
    strncpy(topic, topicName, MAX_GROUP_NAME);
    num = strlen(strncpy(messBuf, topicData, 2047));
    if (num >= 0) {
        int ret = SP_multicast( s_mbox, FIFO_MESS, topic, 1, num, messBuf );
//##    printf("ExcelSpreadPub: SP_multicast sent '%s' to '%s' and returned: '%d'\n", messBuf, topic, ret);
        return ret;
    }
    return -1;
}
#else

DLLIMPORT int pascal 
ExcelSpreadPub_sp_pub_cp(char* topicName, char* topicData )
{
    return -1;
    //return SP_multicast( s_mbox, SAFE_MESS, "foo",             1, 5, "hello" );
}
#endif

#endif


/////////////////////////////// Testing code:



DLLIMPORT double pascal 
ExcelSpreadPub_square (double d)
{
  return d * d;
}
